import { useState, useEffect } from 'react';
import { ethers } from 'ethers';
// import {
//   UNISWAP_ROUTER_ABI, UNISWAP_ROUTER_ADDRESS, ERC20_ABI,
//   TOKEN_A_ADDRESS, TOKEN_B_ADDRESS, UNISWAP_PAIR_ABI, PAIR_ADDRESS
// } from './constants';
import uniswapFactory from '@/abi/uniswapFactory.json';
import uniswapRouter from '@/abi/uniswapRouter.json';
import BscAbi from '@/abi/BscAbi.json';
 import pair from '@/abi/pair.json';
import { useWeb3React } from '@web3-react/core';
const TOKEN_A_ADDRESS='0xFa60D973F7642B748046464e165A65B7323b0DEE'
const TOKEN_B_ADDRESS='0x8d008B313C1d6C7fE2982F62d32Da7507cF43551' 
const UNISWAP_FACTORY_ADDRESS = '0x6725F303b657a9451d8BA641348b6761A6CC7a17';
 
const UNISWAP_ROUTER_ADDRESS = '0xD99D1c33F9fC3444f8101754aBC46c52416550D1';
const PAIR_ADDRESS='0x209eBd953FA5e3fE1375f7Dd0a848A9621e9eaFc' 
const UNISWAP_FACTORY_ABI = uniswapFactory
const UNISWAP_ROUTER_ABI = uniswapRouter
const ERC20_ABI = BscAbi.result
const UNISWAP_PAIR_ABI = pair
function useUniswapSwap() {
  const [provider, setProvider] = useState<ethers.providers.Web3Provider | null>(null);
  const [accounts, setAccounts] = useState<string[]>([]);
  const [uniswapRouter, setUniswapRouter] = useState<ethers.Contract | null>(null);
  const [tokenA, setTokenA] = useState<ethers.Contract | null>(null);
  const [tokenB, setTokenB] = useState<ethers.Contract | null>(null);
  const [pair, setPair] = useState<ethers.Contract | null>(null);
  const [tokenABalance, setTokenABalance] = useState<number>(0);
  const [tokenBBalance, setTokenBBalance] = useState<number>(0);
  const [inputAmount, setInputAmount] = useState<string>('');
  const [outputAmount, setOutputAmount] = useState<number>(0);

  // 初始化 Provider，并获取账号信息
  useEffect(() => {
    const initProvider = async () => {
      try {
        if (window.ethereum) {
          const providerInstance = new ethers.providers.Web3Provider(window.ethereum);
          await window.ethereum.enable();
          setProvider(providerInstance);
        } else {
          throw new Error('Please install MetaMask wallet extension or use other Web3 provider');
        }
      } catch (error) {
        console.error(error);
      }
    };
    initProvider();
  }, []);

  // 初始化 Uniswap 相关合约实例
  useEffect(() => {
    if (provider) {
      const uniswapRouterInstance = new ethers.Contract(
        UNISWAP_ROUTER_ADDRESS,
        UNISWAP_ROUTER_ABI,
        provider,
      );
      setUniswapRouter(uniswapRouterInstance);

      const tokenAInstance = new ethers.Contract(
        TOKEN_A_ADDRESS,
        ERC20_ABI,
        provider.getSigner(), // 这里使用 Signer
      );
      setTokenA(tokenAInstance);

      const tokenBInstance = new ethers.Contract(
        TOKEN_B_ADDRESS,
        ERC20_ABI,
        provider.getSigner(), // 这里使用 Signer
      );
      setTokenB(tokenBInstance);

      const pairInstance = new ethers.Contract(
        PAIR_ADDRESS, 
        UNISWAP_PAIR_ABI,
        provider,
      );
      setPair(pairInstance);
    }
  }, [provider]);

  // 监听账号变化
  useEffect(() => {
    if (provider) {
      const fetchAccounts = async () => {
        try {
          const accountsList = await provider.listAccounts();
          setAccounts(accountsList);
        } catch (error) {
          console.error(error);
        }
      };
      fetchAccounts();
      // 监听账号变化
      provider.on('accountsChanged', fetchAccounts);
    }
  }, [provider]);

  // 获取指定地址在 Uniswap 流动池中的余
  useEffect(() => {
    const getBalance = async () => {
      try {
        const tokenABalanceInWei = await tokenA?.balanceOf(pair?.address);
        const tokenBBalanceInWei = await tokenB?.balanceOf(pair?.address);
        const tokenABalance = parseFloat(ethers.utils.formatUnits(tokenABalanceInWei || 0));
        const tokenBBalance = parseFloat(ethers.utils.formatUnits(tokenBBalanceInWei || 0));
        setTokenABalance(tokenABalance); setTokenBBalance(tokenBBalance);
      }
      catch (error) {
        console.error(error);
      }
    };
    if (pair && tokenA && tokenB) { getBalance(); }
  }, [pair, tokenA, tokenB]);

  // 根据输入 Token A 数量计算将要输出 Token B 的数量
  useEffect(() => {
    const calculateOutputAmount = async () => {
      try {
        const reserves = await pair?.getReserves();
        const amountOut = await uniswapRouter?.getAmountsOut(ethers.utils.parseUnits(inputAmount || '0'),
         [tokenA?.address, tokenB?.address],);
        const outputAmount = ethers.utils.formatUnits(amountOut && amountOut[1] || '0', 'ether');
        console.log(amountOut,'aaaaaaa',outputAmount)
        setOutputAmount(parseFloat(outputAmount));
      }
      catch (error) { console.error(error); }
    };
    if (inputAmount && pair && uniswapRouter && tokenA && tokenB) { calculateOutputAmount(); }
  },
    [inputAmount, pair, uniswapRouter, tokenA, tokenB]);

  // 转换交换的两个 Token 的地址
  const [fromToken, toToken] = parseInt(tokenA?.address || '0', 16) < parseInt(tokenB?.address || '0', 16) ? [tokenA, tokenB] : [tokenB, tokenA];

  // 处理表单提交事件（TokenA -> TokenB） 
  const handleSwap = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault(); try {
      const deadline = Math.floor(Date.now() / 1000) + 60 * 5; // 5 minutes

      // 先批准转账 Token A 给 Uniswap 路由合约使用
      const amountInWei = ethers.utils.parseUnits(inputAmount || '0');
      const approved = await tokenA?.approve(
        UNISWAP_ROUTER_ADDRESS,
        amountInWei,
      );
        console.log(approved,'approved?.hash');
        
      if (approved?.hash) {
        // 等待交易被写入区块链 
        await approved.wait();

        // 调用 swapExactTokensForTokens 方法进行交换
        const amountsOut = await uniswapRouter?.getAmountsOut(
          amountInWei,
          [fromToken?.address, toToken?.address],
        );
        const tokenBAmount = amountsOut && amountsOut[1];
        const tokenAAmount = amountsOut && amountsOut[0];

        if (tokenBAmount && tokenAAmount) {
          const swap = await uniswapRouter?.swapExactTokensForTokens(amountInWei,
            ethers.utils.parseUnits(tokenBAmount.toString()),
            [fromToken?.address, toToken?.address], accounts[0], deadline,);

          // 等待交易被写入区块链
          const transaction = await swap.wait();
          console.log(`Transaction hash: ${transaction.transactionHash}`);

          // 更新余额和输入框
          setInputAmount('');
          setOutputAmount(0);
          const tokenABalanceInWei = await tokenA?.balanceOf(pair?.address);
          const tokenBBalanceInWei = await tokenB?.balanceOf(pair?.address);
          const tokenABalance = parseFloat(ethers.utils.formatUnits(tokenABalanceInWei || 0));
          const tokenBBalance = parseFloat(ethers.utils.formatUnits(tokenBBalanceInWei || 0));
          setTokenABalance(tokenABalance);
          setTokenBBalance(tokenBBalance);
        }
      }
    } catch (error) {
      console.error(error);
    }
  };

  return { inputAmount, outputAmount, tokenA, tokenB, tokenABalance, tokenBBalance, handleSwap, setInputAmount, accounts, };
}

export default useUniswapSwap;